package org.java.order.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.java.order.interceptor.OrderInterceptor;
import org.java.order.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * @author WHQ
 * @version 1.0
 * @date 2022-3-19 0019 下午 3:21
 */
@Aspect
@Component
public class NoRequestSubmitAround {
    @Autowired
    private RedisService redisService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Pointcut("@annotation(org.java.order.aspect.NoRepeatSubmit)")
    public void reqLock(){}
    /**
     * @param point
     */
    @Around("reqLock()")
    public Object constructionSite(ProceedingJoinPoint point) throws Throwable {
        System.out.println("进入环绕通知");
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        //获取注解
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        //目标类、方法
        String className = method.getDeclaringClass().getName();
        String methodName = method.getName();
        //由于使用方法名+用户ID创建的Key，，，必须要有用户id参数
//        Long userId = Long.parseLong(request.getParameter("id"));
        //从载荷中获取用户信息
        Long userId = OrderInterceptor.getUserInfo().getId();
        System.out.println(userId);
//        log.info("防止表单重复提交类：{}. 方法：{}.用户ID：{}.", className, methodName, userId);
        String key = methodName + ":" + userId;
        System.out.println(key);
        NoRepeatSubmit noRepeatSubmit = method.getAnnotation(NoRepeatSubmit.class);
        long timeout = noRepeatSubmit.timeout();
        if (timeout < 0) {
            //过期时间10分钟
            timeout = 10;
        }
        //校验该方法该用户的key是否存在，存在直接返回错误
        if (!stringRedisTemplate.opsForValue().setIfAbsent(key,new Date().toString())) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
        }
//        boolean b = redisService.addString(key, new Date().toString(), timeout, TimeUnit.MINUTES);
//        log.info("创建锁结果:{}. key:{}.", b, key);
        //执行方法
        Object object = point.proceed();
        System.out.println("离开环绕通知");
        //整理施工现场,方法执行结束，删除键
        stringRedisTemplate.delete(key);
        return object;
    }

}
